from datetime import datetime

from flask import render_template, flash, redirect, request, abort, url_for, g
from flask_login import current_user

from app import login_required_with_check_scope

from app.model.base import db
from app.model.order import Order, OrderStatus
from app.validator.order import OrderPayForm, NewOrderForm
from app.web import web


@web.route('/order/list', methods=['get'])
@login_required_with_check_scope
def order_list_ep():
    """
        普通用户订单列表路由

    :arg:
        k: 搜索关键词, 可空

    :return:
        orders: 订单列表
    """
    k = request.args.get('k', '', str)
    p = request.args.get('p', 1, int)
    pagination = Order.query.filter(
        Order.user_id == current_user.id, Order.product_name.like('%' + k + '%')
    ).order_by(
        Order.create_time.desc()
    ).paginate(p, per_page=5)
    orders = pagination.items
    return render_template('web/order/list.html', orders=orders, pagination=pagination)


@web.route('/order/new', methods=['post'])
@login_required_with_check_scope
def new_order_ep():
    """
        普通用户创建订单路由

    :form:
        product_id: 商品id
        count: 购买数量

    :return:
        if success: 重定向到订单详情页
        if exception: 重定向到来源页面（若没有则重定向到首页）
    """
    form = NewOrderForm(request.form)
    if not form.validate():
        flash(form.errors, 'form')
        # 参数有问题，重定向到来源页面（若没有则重定向到首页）
        return redirect(request.referrer or url_for('web.product_list_ep'))
    product = g.product

    # 新建订单并减少目标商品库存
    with db.auto_commit():
        order = Order.create(product, current_user, form.count.data)
        db.session.add(order)
        product.reduce(form.count.data)

    return redirect(url_for('web.order_detail_ep', order_id=order.id))


@web.route('/order/pay', methods=['post'])
@login_required_with_check_scope
def pay_order_ep():
    """
        普通用户支付订单

    :json:
        order_id: 订单id

    :return: 'success' or 'fail'
    """
    form = OrderPayForm(data=request.json)
    if not form.validate():
        return 'fail'
    with db.auto_commit():
        g.order.paid()
    return 'success'


@web.route('/order/<order_id>', methods=['get'])
@login_required_with_check_scope
def order_detail_ep(order_id):
    """
        普通用户查看订单详情路由

    :param
        order_id: 订单id
    """
    order = Order.query.filter_by(id=order_id).first()
    if not order or order.user_id != current_user.id:
        abort(404)
    return render_template('web/order/detail.html', order=order)


@web.route('/order/finish', methods=['post'])
@login_required_with_check_scope
def order_finish_ep():
    """
        普通用户收货操作路由

    :form:
        order_id: 订单id
    """
    order_id = request.form.get('order_id', type=str)
    order = Order.query.filter_by(id=order_id).first()
    if order and order.user_id == current_user.id:
        with db.auto_commit():
            order.finish()
    return redirect(request.referrer)


@web.route('/order/request_cancel', methods=['post'])
@login_required_with_check_scope
def order_cancel_ep():
    """
        普通用户申请取消订单路由

    :form:
        order_id: 订单id
    """
    order_id = request.form.get('order_id', type=str)
    order = Order.query.filter_by(id=order_id).first()
    # 只能取消自己的没有确认收货的订单
    if order and order.user_id == current_user.id and OrderStatus(order.status).value < 3:
        with db.auto_commit():
            order.request_cancel()
    return redirect(request.referrer)
